package com.example.udp.gala;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import cn.hutool.core.util.HexUtil;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class GalaUdpServer {
    private static DatagramChannel channel;



    @Scheduled(initialDelay=1000, fixedRate = 10000)
    public void send() throws IOException {
        // 如果channel没有初始化成功，跳过
        System.out.println("执行定时任务");

        if (channel == null || !channel.isOpen()) {
            return;
        }
        for (int i = 1; i <= 255; i++) {
            System.out.println("发送数据到192.168.200."+i);
            send("192.168.131."+i, 6000, new byte[] { 0x50, 0x02 });
        }
    }

    /**
     * 启动UDP服务器
     */
    @Async
    public void startListenUdp() {
        System.out.println("服务器启动成功，等待客户端连接...");

        try (
                final Selector selector = Selector.open();) {

            channel = DatagramChannel.open();
            final ByteBuffer buffer = ByteBuffer.allocate(1024);
            channel.configureBlocking(false);
            channel.bind(new InetSocketAddress("0.0.0.0", 30778));
            channel.register(selector, SelectionKey.OP_READ);
            // 通过选择器，查询IO事件
            while (selector.select() > 0) {
                final Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    final SelectionKey selectionKey = iterator.next();
                    // 可读事件，有数据到来
                    if (selectionKey.isReadable()) {
                        buffer.clear(); // 清空缓冲区准备接收新数据
                        final SocketAddress client = channel.receive(buffer);
                        if (client instanceof InetSocketAddress) {
                            InetSocketAddress inetSocketAddress = (InetSocketAddress) client;
                            String clientIP = inetSocketAddress.getAddress().getHostAddress();
                            int clientPort = inetSocketAddress.getPort();
                            System.out.println("客户端IP:" + clientIP + " 端口:" + clientPort);
//                            send(clientIP, clientPort, new byte[] { 0x4f, 0x01 });
                        }
                        buffer.flip();
                        byte[] receivedData = Arrays.copyOfRange(buffer.array(), 0, buffer.limit());
                        handleReceivedData(receivedData); // 处理接收到的数据
                    }
                }
                iterator.remove();
            }
        } catch (IOException ioException) {
            // 捕获并处理 IOException
            System.err.println("Error receiving data: " + ioException.getMessage());
            ioException.printStackTrace();
        } finally {
            try {
                channel.close();
            } catch (IOException e) {
                System.err.println("Error receiving data2: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    // 处理接收到的字节数组的方法
    private void handleReceivedData(byte[] data) {
        if(data == null || data.length == 0) return;
        System.out.println("收到客户端消息：" + HexUtil.encodeHexStr(data));
    }

    /**
     * 获取用户输入的数据，发送到远程服务器
     */
    public void send(String ip, int port, byte[] input) throws IOException {
        try {
            final ByteBuffer buffer = ByteBuffer.wrap(input);
            channel.send(buffer, new InetSocketAddress(ip, port));
        } catch (IOException e) {
            System.err.println("发送失败: " + e.getMessage());
        }
    }

}
